<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<link rel="stylesheet" href="caom.css">
<title>
	Common Archive Observation Model
</title>
</head>

<body>

<div class="main">

<h1>Common Archive Observation Model (CAOM-2.0)</h1>

<p>
The Common Archive Observation Model (CAOM) is a general purpose data model for
use as the core data model of an astronomical data centre. The purpose of this
model is to standardize the core parts of every archive implementation so that
a common set of software tools can be used across archives. This set of tools
includes simple data access mechanisms (web pages), discovery agents,
advanced query capabilities (typically as IVOA web services), and advanced applications.
In addition, we have implemented CAOM in a cross-archive data warehouse which will hold
metadata for all public and proprietary data; the common model is used
within the data warehouse and thus defines the portion of the archive database
that is available through all applications.
</p>

<p>
    While the previous version (CAOM-1.0) was very successful in enabling the CADC to serve a wide variety of data, some particular
    data structures were awkward to describe in a meaningful way. CAOM-2.0 has been developed to address such issues and cover new
    scenarios for data products.
</p>

<h2>CAOM-2.0 Software</h2>

<div class="table">
<table class="content">
    <tr>
        <th>resource</th><th>description</th>
    </tr>
    <tr>
        <td><a href="http://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/tap/">Table&nbsp;Access&nbsp;Protocol&nbsp;(TAP)</a></td>
        <td>a web service for ad-hoc querying, including both CAOM-2.0 and the IVOA ObsCore-1.0 Data Model</td>
    </tr>
    <tr class="even">
        <td><a href="http://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/sia/">Simple&nbsp;Image&nbsp;Access&nbsp;(SIA)</a></td>
        <td> a web service for finding calibrated images (uses TAP and CAOM-2.0)</td>
    </tr>
    <tr class="odd">
        <td><a href="http://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/AdvancedSearch/">AdvancedSearch</a></td>
        <td>a user interface for querying CAOM (uses TAP)</td>
    </tr>
    
    <tr class="even">
        <td><a href="http://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/caom2repo/">CAOM-2.0 observation repository</a></td>
        <td>web service to support ingestion of data to CAOM-2.0 at CADC (requires authentication)</td>
    </tr>
    
    <tr class="odd">
        <td><b>caom2</b></td>
        <td>java library for manipulating CAOM-2.0 observations, including reading and writing XML documents
            <br><a href="http://code.google.com/p/caom/">source code</a></td>
    </tr>
    
    <tr class="even">
        <td><b>fits2caom2</b></td>
        <td>java command-line tool for extracting metadata from FITS files, reads FITS file(s) and writes an XML document
            <br><a href="http://code.google.com/p/caom/">source code</a></td>
    </tr>
    
    <tr class="odd">
        <td><b>pyCAOM2</b></td>
        <td>python library for manipulating CAOM-2.0 observations, including reading and writing XML documents
            <br><a href="http://code.google.com/p/caom/">source code</a></td>
    </tr>
    
    <tr class="even">
        <td><b>caom2repoClient</b></td>
        <td>python command-line tool for interacting with the CAOM-2.0 observation repository, supports
            get, put, update, delete (requires authentication)
            <br><a href="http://code.google.com/p/caom/">source code</a></td>
    </tr>
    
    <tr class="odd">
        <td><b>cadcWCS</b></td>
        <td>java library for accessing <a href="http://www.atnf.csiro.au/people/mcalabre/WCS/">wcslib</a>
            <br><a href="http://code.google.com/p/opencadc/">source code</a></td>
    </tr>
    
    <tr class="even">
        <td><b>wcsLibJNI</b></td>
        <td>JNI binding library for <a href="http://www.atnf.csiro.au/people/mcalabre/WCS/">wcslib</a>
            <br><a href="http://code.google.com/p/opencadc/">source code</a></td>
    </tr>
    
</table>
</div>


<h2>Core Classes</h2>

<p>
The core CAOM classes describe the observation, data products, and access to the
physical artifacts (typically files), as well as the provenance of the data products.
In addition, we also show the (loosely coupled) metadata access control classes.
</p>
<p>
The UML diagrams specify through the cardinality whether an object or field may be null or not.
</p>
<ul>
    <li>no visible cardinality means 1: the value is mandatory</li>
    <li>0..1 compositions (solid black diamond at start) are equivalent to member variables; the value is optional</li>
    <li>n..* compositions signify a collection which is never null, but may be empty for n = 0</li>
</ul>

<p>
While there are a few methods shown in the model, these are to signify value conversions (e.g. wavelength to frequency) that
require access to other internal fields; this is a reminder/hint to persistence implementations that the values returned from
methods should also be stored for efficient querying (for example, by the TAP service).
</p>

<a href="uml/CAOM1core.png">  <img src="uml/CAOM1core.png" alt="core CAOM model"></a>

<h3>Changes</h3>

<ul>
	<li>2014-11-18 (red outline): added Observation.requirements with a Status flag; added Plane.qualityFlag; moved 
		all vocabularies (enumerations) a separate diagram (below)
    <li>2014-02-10: added restwav (observed rest wavelength) to computed plane energy metadata
    <li>2013-11-26: added moving flag to Target class, added TargetPosition class
    <li>2013-09-08: added PolarizationState literals: POLI (polarized intensity), FPOLI (fractional polarized intensity), 
        POLA (linear polarized angle), EPOLI (elliptical polarized intensity), CPOLI (circular polarized intensity), 
        and NPOLI (non-polarized intensity)
    <li>2013-06-18: added CATALOG, NOISE, and WEIGHT as additional ProductType literals (used to all be classified as AUXILIARY)
    <li>2012-11-20: added timesys, trefpos, and mjdref to TemporalWCS (from the draft FITS TimeWCS paper); time values
        in the CoordAxis1D are still restricted to MJD only as they are numbers and and we would need another field to allow JD; if
        mjdref is null, the values are absolute (otherwise they are relative to mjdref)
    <li>2012-07-31: renamed DataProcess to Provenance, changed Plane.position.timeDependent to
        be a Boolean (null allowed)
    <li>2012-06-20: removed partName - partNumber distinction and just use a required
        Part.name field
    <li>2012-06-20: made Observation.target.type optional, removed ProcessMetaReadAccess
        since provenance is now part of one plane (access is controlled by PlaneMetaReadAccess),
        added Observation.type (typically OBSTYPE from FITS) and Observation.intent (science or
        calibration)
    <li>2012-06-07: removed Plane.observable since it is not sensible to summarise multiple
        Chunk.observable values and chunks with one observable will usually leave it blank
    </li>
    <li>2012-03-26: added various ASMD fields, refactored Metric to be a fixed set of
        Plane.metrics.* fields
    </li>
    <li>2012-03-15: added cardinality to keywords fields to show they are lists of strings<br/>
        changed Plane.observable to have a simple name and units instead of re-using Axis<br/>
        removed Target.position field
    </li>

    <li>2012-02-17: change Plane.dataType to Plane.dataProductType</li>
    <li>
	2012-02-15: Refactored provenance to be a single class owned by and characterising a single plane<br/>
	made Metric.error a field (nullable), but utility of current design is under consideration<br/>
	specified cardinality of keywords to be [0..*] to signify a list of strings<br/>
	refactored Observable, but current design is under consideration<br/>
	removed Plane.dataStatus and the DataStatus enumerated type (no use case)<br/>
	refactored Part so that partName and partNumber are immutable state<br/>
	
    </li>
    <li>
        2012-01-27: Added convenience methods to Energy to return the width of the energy bounds and the sample size in
        frequency (the bounds and sampleSize fields are wavelength)
    </li>
    
</ul>

<p>
All the mini-vocabularies defined in the CAOM model are shown below. More detailed definitions and actual
literal values used when stored or serialised follow.
</p>

<a href="uml.CAOM5vocabularies.png"> <img src="uml/CAOM5vocabularies.png" alt="CAOM vocabularies"></a>

<h3>Changes</h3>
<ul>
	<li>2014-11-18 (red outline): separate vocabulary (enumerations) diagram, added Status and Quality; 
        removed ProductType.CATALOG value</li>
</ul>

<h3>Observation</h3>

<p>
An observation is the primary top-level class for empirical data. A simple observation is the
result of one use or invocation of a telescope and instrument, while a composite observation is a
collection of simple observations that have been combined to create a new data product.
simple observations have one or more data products (planes). The metadata for an observation is
concerned with describing the data acquisition: the proposal, telescope, instrument, and target.
The algorithm for a simple observation is always <em>exposure</em> while the algorithm for a
composite observation describes the semantics of the grouping or composition involved.
</p>

<p>
Enumerated type values are generally lower case strings equivalent to the names used in the model, but there
are a few exceptions where numeric values or mixed-case strings from an external source are used.
</p>

<div class="table">
<table class="content">
    <tr>
        <th>Enumeration</th><th>model field</th><th>serialised value</th><th>description</th>
    </tr>
    <tr class="even">
        <td>ObservationIntentType</td>
        <td/><td/><td>describes the intent of the observation</td>
    </tr>
    <tr>
        <td></td><td>SCIENCE</td><td>science</td><td></td>
    </tr>
    <tr>
        <td></td><td>CALIBRATION</td><td>calibration</td><td></td>
    </tr>
    <tr class="even">
        <td>TargetType</td>
        <td/><td/><td>describes the type of target (e.g. FITS OBSTYPE keyword)</td>
    </tr>
    <tr>
        <td></td><td>OBJECT</td><td>object</td><td></td>
    </tr>
    <tr>
        <td></td><td>FIELD</td><td>field</td><td></td>
    </tr>
	<tr class="even">
        <td>Status</td>
        <td/><td/><td>flag to characterise the satisfaction of requirements</td>
    </tr>
    <tr>
        <td></td><td>FAIL</td><td>fail</td><td></td>
    </tr>
</table>
</div>

<h3>Plane</h3>

<p>
A plane is one (of several) data product(s) that are created as part of an observation. Each
simple observation typically has one <em>raw</em> plane created by the observing process itself and may
have one or more additional planes that are produced by subsequent data processing. The metadata
for a plane characterises the data product: the coverage and sampling in position, energy, time,
and polarization, a description of the observed quantity (usually something proportional to flux).
This metadata is generally computed from the artifact metadata and is used primarily in data discovery.
</p>

<div class="table">
<table class="content">
    <tr>
        <th>Enumeration</th><th>model field</th><th>serialised value</th><th>description</th>
    </tr>
    <tr class="even">
        <td>CalibrationLevel</td>
        <td/><td/><td>from IVOA <a href="http://www.ivoa.net/Documents/ObsCore/index.html">ObsCoreDM-1.0</a></td>
    </tr>
    <tr>
        <td></td><td>RAW_INSTRUMENTAL</td><td>0</td><td>raw data, instrumental format</td>
    </tr>
    <tr>
        <td></td><td>RAW_STANDARD</td><td>1</td><td>raw data, standard format</td>
    </tr>
    <tr>
        <td></td><td>CALIBRATED</td><td>2</td><td>calibrated data, standard reductions appleid</td>
    </tr>
    <tr>
        <td></td><td>PRODUCT</td><td>3</td><td>product, advanced processing applied</td>
    </tr>
    <tr class="even">
        <td>DataProductType</td>
        <td/><td/><td>from IVOA <a href="http://www.ivoa.net/Documents/ObsCore/index.html">ObsCoreDM-1.0</a></td>
    </tr>
    <tr>
        <td></td><td>IMAGE</td><td>image</td><td></td>
    </tr>
    <tr>
        <td></td><td>SPECTRUM</td><td>spectrum</td><td></td>
    </tr>
    <tr>
        <td></td><td>TIMESERIES</td><td>timeseries</td><td></td>
    </tr>
    <tr>
        <td></td><td>VISIBILITY</td><td>visibility</td><td></td>
    </tr>
    <tr>
        <td></td><td>EVENTLIST</td><td>eventlist</td><td></td>
    </tr>
    <tr>
        <td></td><td>CUBE</td><td>cube</td><td></td>
    </tr>
    <tr>
        <td></td><td>CATALOG</td><td>catalog</td><td>custom data product type</td>
    </tr>
    <tr class="even">
        <td>EnergyBand</td>
        <td/><td/><td>from IVOA <a href="http://www.ivoa.net/Documents/latest/RM.html">Resource Metadata for the Virtual Observatory</a></td>
    </tr>
    <tr>
        <td></td><td>RADIO</td><td>Radio</td><td>nu &gt; 30GHz (lambda &lt; 10mm)</td>
    </tr>
    <tr>
        <td></td><td>MILLIMETER</td><td>Millimeter</td><td>0.1-10mm</td>
    </tr>
    <tr>
        <td></td><td>INFRARED</td><td>Infrared</td><td>1-100um</td>
    </tr>
    <tr>
        <td></td><td>OPTICAL</td><td>Optical</td><td>300-1000nm</td>
    </tr>
    <tr>
        <td></td><td>UV</td><td>UV</td><td>100-300nm</td>
    </tr>
    <tr>
        <td></td><td>EUV</td><td>EUV</td><td>10-100nm</td>
    </tr>
    <tr>
        <td></td><td>XRAY</td><td>X-ray</td><td>0.12-120keV</td>
    </tr>
    <tr>
        <td></td><td>GAMMARAY</td><td>Gamma-ray</td><td>energy &gt; 120keV</td>
    </tr>
	<tr class="even">
        <td>Quality</td>
        <td/><td/><td>flag data quality</td>
    </tr>
    <tr>
        <td></td><td>JUNK</td><td>junk</td><td>this data is bad for everything</td>
    </tr>
</table>
</div>

<p>
The serialised values for Polarization (as listed in the PolarizationState type) are the identical upper case letter(s).
</p>

<h3>Artifact</h3>

<p>
An artifact is one physical product or resource (typically a file) that is part of a plane. Planes in an Observation with intent=science
should always have at least one <em>science</em> artifact and may have other types of (associated) artifacts. Planes in an Observation 
with intent=calibration should always have at least one <em>calibration</em> artifact and may have other types of (associated) artifacts. While
science Observations (with science Artifacts) could also contain calibration Artifacts, this should only be done if those calibrations are to be used
with that science data only; normally science and calibration files are part of different Observations.
</p>

<div class="table">
<table class="content">
    <tr>
        <th>Enumeration</th><th>model field</th><th>serialised value</th><th>description</th>
    </tr>
    <tr class="even">
        <td>ProductType</td>
        <td/><td/><td>file type classification</td>
    </tr>
    <tr>
        <td></td><td>SCIENCE</td><td>science</td><td>science data</td>
    </tr>
    <tr>
        <td></td><td>CALIBRATION</td><td>calibration</td><td>files needed to calibrate science data</td>
    </tr>
    <tr>
        <td></td><td>INFO</td><td>info</td><td>additional information file(s), usually text</td>
    </tr>
    <tr>
        <td></td><td>PREVIEW</td><td>preview</td><td>non-science quality rendition of the data for preview</td>
    </tr>
     <tr>
        <td></td><td>NOISE</td><td>noise</td><td>associated noise files needed for analysis</td>
    </tr>
     <tr>
        <td></td><td>WEIGHT</td><td>weight</td><td>associated weight files needed for analysis</td>
    </tr>
     <tr>
        <td></td><td>AUXILIARY</td><td>auxiliary</td><td>other associated files needed for analysis</td>
    </tr>
</table>
</div>

<h3>Part</h3>

<p>
A part is one qualitatively defined subsection of an artifact. For example, if the artifact is a
multi-extension FITS file, it would have one part for each extension. If the artifact is a tar or
zip file, it would have one part for each contained file.
</p>

<h3>Chunk</h3>

<p>
A chunk is a quantitatively defined subsection of a part. The chunk is characterised by
world coordinate system (WCS) metadata plus an extra axis to describe different observables
(the measured values) stored within the data. Different chunks can be defined which vary only
on the range of coordinate values they include. For example, if a single data array
contains different observable quantities can define a chunk for each slice through the array, with
each slice having a different product type. One can also use chunks to define arbitrary tiles
in a large data array; this is useful if there is no WCS solution to describe the mapping of sky
to pixel coordinates but one still wants to be able to extract smaller sections of the data (e.g.
one chunk).
</p>

<h3>Metric</h3>

<p>
A metric is a measured quantity that described a data product. Metrics are inherently very flexible
and can be used to derive interesting and useful metadata about data products, usually by analysing
the actual content and computing some aggregate information. For example, one could compute the
number (or density) of point and extended sources in an image or the signal-to-noise ratio of a
specific type and brightness of source. Metrics describe the content of the data product.
</p>

<h3>Provenance</h3>

<p>
The provenance of a data product describes the data processing that transformed the input(s) into
the output. For example, a <em>raw</em> plane is processed to produce a <em>calibrated</em> plane using
a specific recipe. This is considered provenance since the primary goal or view of this metadata is to
understand how a specific plane was produced and to trace backwards from an output, through the
data process, to the input(s). The complete provenance may include multiple loops until it reaches a
plane which does not have a provenance: a <em>raw</em> plane in a simple observation.
</p>

<h3>ReadAccess and Subclasses</h3>

<p>
Access control is declared as special permission classes where the existence of instances grants
read permission on instances of associated assets. In addition to the permissions, assets also
include a <em>release date</em> (e.g. metaRelease in the Plane class) that specifies when the asset is
public and permission is not required. For example, instances of the PlaneMetaReadAccess
class grant read permission on the metadata held in the an instance of the Plane class (where the
assetID of the permission matches the ID of the asset). Access control is implemented as a query
transformation (e.g. in a TAP service) that connects the asset and the permission and allows one to
implement and protect proprietary metadata within CAOM.
</p>

<h3>IVOA Publisher Dataset Identifiers</h3>

<p>
The IVOA publisher dataset identifier (publisherDID) is a Uniform Resource Identifier (URI).
In CAOM, this is a reproducible, globally-unique identifier, constructed as follows:
</p>
<p>
<code>ivo://{authority}/{collection}/{observationID}/{productID}</code>
</p>
<p>
where the curly braces { } denote values from the model (or a registered IVOA Authority ID
in the case of {authority}). Within one authority (data centre), the collection and observationID
from the Observation class and the productID from the Plane class make up the publishderDID
for a single CAOM data product. It is not clear exactly how one resolves a publisherDID, but
what one can do is strip the path off and look up the authority in an IVOA registry and then
look up specific types of IVOA services owned by that authority, such as the proposed
DataLink service.
</p>

<h2>Data Types (Discovery)</h2>

<p>
    The following data types are used in the computed characterisation of the Plane
    class to support data discovery queries.
</p>
<a href="uml/CAOM2datatypes.png">  <img src="uml/CAOM2datatypes.png" alt="core CAOM model"></a>

<h3>Changes</h3>

<ul>
    <li>2013-09-08: added PolarizationState literals: POLI (polarized intensity), FPOLI (fractional polarized intensity), 
        POLA (linear polarized angle), EPOLI (elliptical polarized intensity), CPOLI (circular polarized intensity), 
        and NPOLI (non-polarized intensity)</li>
    <li>2012-02-15: made Location contain coordinates rather than be a subclass for symmetry</li>
    <li>added Box datatype</li>
    <li>changed some fields to methods to correctly specify required and immutable state</li>
</ul>

<h2>Data Types (WCS)</h2>

<p>
    The following data types are derived from FITS WCS (TODO: ref), but also include more
    general ability to describe coverage when per-pixel coordinate system information is not
    available (for example, raw data that is not in FITS format) or is not practical to store
    in the database (for example, non-linear spectral WCS solution stored in the data array
    or table of a FITS file).
</p>
<a href="uml/CAOM3wcs.png">  <img src="uml/CAOM3wcs.png" alt="core CAOM model"></a>

<p>
The PolarizationState enumeration that describes polarization of a Plane is computed from the FITS WCS description
of the axis (CTYPEi=STOKES). The numeric values used in the FITS WCS representation are related to the string values
following FITS WCS Paper 1 (Table 7) and some extensions extracted from a 
<a href="http://listmgr.cv.nrao.edu/pipermail/fitswcs/2008-March/000408.html">fits mailing list discusssion</a>.
The mapping is as follows:
</p>

<div class="table">
<table class="content">
    <tr>
        <th>PolarizationState</th><th>numeric value</th><th>description/source</th>
    </tr>
    <tr class="even">
        <td>I</td><td>1</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>Q</td><td>2</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>U</td><td>3</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>V</td><td>4</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>POLI</td><td>5</td><td>linear polarized intensity sqrt(Q^2 + U^2), code used in AIPS</td>
    </tr>
    <tr class="even">
        <td>FPOLI</td><td>6</td><td>fractional linear polarization POLI/I, code used in AIPS</td>
    </tr>
    <tr class="even">
        <td>POLA</td><td>7</td><td>linear polarization angle 1/2 arctan(U,Q), code used in AIPS</td>
    </tr>
    <tr class="even">
        <td>EPOLI</td><td>8</td><td>elliptical polarization intensity sqrt(Q^2 + U^2 + V^2)</td>
    </tr>
    <tr class="even">
        <td>CPOLI</td><td>9</td><td>circular polarization intensity |V|</td>
    </tr>
    <tr class="even">
        <td>NPOLI</td><td>10</td><td>unpolarized intensity I - EPOLI</td>
    </tr>
    <tr class="even">
        <td>RR</td><td>-1</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>LL</td><td>-2</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>RL</td><td>-3</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>LR</td><td>-4</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>XX</td><td>-5</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>YY</td><td>-6</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>XY</td><td>-7</td><td>FITS WCS Paper 1</td>
    </tr>
    <tr class="even">
        <td>YX</td><td>-8</td><td>FITS WCS Paper 1</td>
    </tr>
</table>
</div>

<h3>Changes</h3>

<ul>
    <li>2012-11-20: added timesys and trefpos to TemporalWCS (from the draft FITS TimeWCS paper); time values
        in the CoordAxis1D are still restricted to MJD only as they are numbers and and we would need a boolean to allow JD;
        example usage from draft paper: CTYPE=TIME and TIMESYS=UTC is equivalent to CTYPE=UTC and TIMESYS=null
    <li>2012-03-15: changed Slice to have methods that reflect immutable state<br/>
        changed SpectralWCS.specsys to be a method since a value is mandatory<br/>
        removed extraneous get methods from CoordAxis1D and CoordAxis2D
    </li>
    <li>2012-02-22: Changed Error class to CoordError to avoid annoying code conflict with
        java.lang.Error since that package is always in scope
    </li>
    <li>
    2012-02-15: removed get methods from CoordAxis1D and CoordAxis2D that were utilities for
    computing information and not signifying state<br/>
    renamed bounds and footprint to range and bounds respectively
    changed CoordAxis1D.axis from field to getAxis method (not nullable)
    </li>
    <li>
        2012-01-27: Added support for a circular footprint (in addition to polygon) to better
        capture a single beam in radio data; still need to determine the impact of the use of
        polymorphism on persistence implementation
    </li>
    <li>changed some fields to methods to correctly specify required and immutable state</li>
</ul>

<h2>Persistence Interfaces</h2>

<p>
    Once of the goals for CAOM is to enable instances of observations to be harvested to
    alternate databases. To support this, all CAOM <i>entities</i> have a unique identifier to
    support fine-grained updating of existing records and a last-modified timestamp to support
    incremental harvesting (normally only detect and harvest changed entities).
</p>

<a href="uml/CAOM4entities.png">  <img src="uml/CAOM4entities.png" alt="core CAOM model"></a>

<h3>Changes</h3>

<ul>
    <li>
    2012-02-15: DataProcess was renamed to provenance and is no longer a distinct CaomEntity
    </li>
</ul>


<h1>Important Changes Since CAOM-1.0</h1>

<p>
    Below are the main differences between the previous and current versions of
    CAOM. This is not a complete changelog, but it does try to capture the main
    differences.
</p>

<ul>
    <li>metadata that used to be specified for SimpleObservation or
        CompositeObservation is moved into the base Observation class: for simple
        observations these value retain the original meaning, while for composites the
        values simply mean that all the members had the same value (practically,
        CompositeObservations are almost always made from data with the same
        telescope and instrument and often the same target and proposal)
    </li>
    <li>the Artifact class is normalised into to three separate classes:
        Artifact, Part, and Chunk: Artifact is a <i>whole</i> thing (typically file),
        Part is a qualitative subsection (typically a single FITS extension), and Chunk
        is a quantitateivly defined subsection (typically a single row or column from a
        table or data array, but could be extended to support an arbitrary list of range
        of values if this actually occurs in reality)
    </li>
    <li>the Metric class is a part of the plane with specific metrics defined</li>
    <li>WCS classes are no longer entities that can be shared by multiple Artifacts</li>
    <li>add support for non-science artifacts to be included within a plane
        instead of as separate, related planes</li>
    <li>added an ObservableAxis to support cases where different quantities are
        stored in different sections of a data array: the use cases that drive this also
        require the Chunk and typically each Chunk is a different observable slice in the
        data array, but it could be used as a tiling mechanism
    </li>
    <li>integrated provenance model</li>
    <li>integrated metadata access control model</li>
    <li>renamed the permanent observation identifier from collectionID to observationID</li>
    <li>added a permanent product identifier (productID) to the Plane class</li>
    <li>expanded the WCS classes to include less detailed characterisation when a
        complete WCS solution is not available or practical</li>
    <li>added &lt;&lt;computed&gt;&gt; stereotype so that computed (aggreggate) 
        metadata was clearly marked</li>
    <li>made the rules for specifying whether null values are allowed or not
        follow clearly from the model</li>
</ul>

</div>

</body>
</html>
